using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.Autofac;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Sqlite;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
using Matrix.Notification.EntityFrameworkCore;

namespace Matrix.Notification.Tests
{
    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpTestBaseModule),
        typeof(AbpEntityFrameworkCoreModule),
        typeof(AbpEntityFrameworkCoreSqliteModule),
        typeof(MatrixNotificationDomainModule),
        typeof(MatrixNotificationEntityFrameworkCoreModule)
    )]
    public class NotificationTestModule : AbpModule
    {
        private SqliteConnection? _sqliteConnection;

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddAlwaysDisableUnitOfWorkTransaction();

            Configure<AbpDbContextOptions>(options =>
            {
                options.Configure(abpDbContextConfigurationContext =>
                {
                    abpDbContextConfigurationContext.DbContextOptions.UseSqlite(CreateDatabase(abpDbContextConfigurationContext.Connection));
                });
            });

            context.Services.AddEntityFrameworkInMemoryDbContext<NotificationDbContext>(options =>
            {
                options.UseInMemoryDatabase("NotificationTestDb");
            });
        }

        public override void OnApplicationShutdown(ApplicationShutdownContext context)
        {
            _sqliteConnection?.Dispose();
        }

        private static SqliteConnection CreateDatabase(IInfrastructure<DbConnection> connection)
        {
            var sqliteConnection = new SqliteConnection("DataSource=:memory:");
            sqliteConnection.Open();

            var options = new DbContextOptionsBuilder<NotificationDbContext>()
                .UseSqlite(sqliteConnection)
                .Options;

            using var dbContext = new NotificationDbContext(options);
            dbContext.GetService<IRelationalDatabaseCreator>().CreateTables();

            return sqliteConnection;
        }
    }
}